bin/commit: Add '=' to --statoverride
authorColin Walters <walters@verbum.org>
Fri, 30 Jun 2017 13:40:37 +0000 (09:40 -0400)
committerAtomic Bot <atomic-devel@projectatomic.io>
Fri, 30 Jun 2017 21:23:48 +0000 (21:23 +0000)
Previously, we only supported additions in the statoverride file;
it was mainly for adding the setuid bit without having that physically
on disk.

However, for testing a change to `bare-user` handling around *unreadable*
files (which happens for `/etc/shadow` in host content), I need a way
to write that into a repo in the test suite.

I'm not actually aware of a non-test-suite use case for this; a more
sophisticated user is going to be using the API directly, which can already do
this. But we need it for tests at least.

Closes: #989
Approved by: jlebon

src/ostree/ot-builtin-commit.c
tests/basic-test.sh

index 77dafdfbcbcad8b3860c668e2fb78eb12c6aa22c..8e8b9233ff6b85cee0d5a70339e6d72ac10dd4e3 100644 (file)
@@ -126,19 +126,35 @@ parse_file_by_line (const char    *path,
   return TRUE;
 }
 
+struct CommitFilterData {
+  GHashTable *mode_adds;
+  GHashTable *mode_overrides;
+  GHashTable *skip_list;
+};
+
 static gboolean
 handle_statoverride_line (const char  *line,
                           void        *data,
                           GError     **error)
 {
-  GHashTable *files = data;
+  struct CommitFilterData *cf = data;
   const char *spc = strchr (line, ' ');
   if (spc == NULL)
     return glnx_throw (error, "Malformed statoverride file (no space found)");
+  const char *fn = spc + 1;
 
-  guint mode_add = (guint32)(gint32)g_ascii_strtod (line, NULL);
-  g_hash_table_insert (files, g_strdup (spc + 1),
-                       GUINT_TO_POINTER((gint32)mode_add));
+  if (g_str_has_prefix (line, "="))
+    {
+      guint mode_override = (guint32)(gint32)g_ascii_strtod (line+1, NULL);
+      g_hash_table_insert (cf->mode_overrides, g_strdup (fn),
+                           GUINT_TO_POINTER((gint32)mode_override));
+    }
+  else
+    {
+      guint mode_add = (guint32)(gint32)g_ascii_strtod (line, NULL);
+      g_hash_table_insert (cf->mode_adds, g_strdup (fn),
+                           GUINT_TO_POINTER((gint32)mode_add));
+    }
   return TRUE;
 }
 
@@ -152,11 +168,6 @@ handle_skiplist_line (const char  *line,
   return TRUE;
 }
 
-struct CommitFilterData {
-  GHashTable *mode_adds;
-  GHashTable *skip_list;
-};
-
 static OstreeRepoCommitFilterResult
 commit_filter (OstreeRepo         *self,
                const char         *path,
@@ -165,6 +176,7 @@ commit_filter (OstreeRepo         *self,
 {
   struct CommitFilterData *data = user_data;
   GHashTable *mode_adds = data->mode_adds;
+  GHashTable *mode_overrides = data->mode_overrides;
   GHashTable *skip_list = data->skip_list;
   gpointer value;
 
@@ -181,6 +193,14 @@ commit_filter (OstreeRepo         *self,
                                         current_mode | mode_add);
       g_hash_table_remove (mode_adds, path);
     }
+  else if (mode_overrides && g_hash_table_lookup_extended (mode_overrides, path, NULL, &value))
+    {
+      guint current_fmt = g_file_info_get_attribute_uint32 (file_info, "unix::mode") & S_IFMT;
+      guint mode_override = GPOINTER_TO_UINT (value);
+      g_file_info_set_attribute_uint32 (file_info, "unix::mode",
+                                        current_fmt | mode_override);
+      g_hash_table_remove (mode_adds, path);
+    }
 
   if (skip_list && g_hash_table_contains (skip_list, path))
     {
@@ -299,6 +319,7 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
   glnx_unref_object OstreeMutableTree *mtree = NULL;
   g_autofree char *tree_type = NULL;
   g_autoptr(GHashTable) mode_adds = NULL;
+  g_autoptr(GHashTable) mode_overrides = NULL;
   g_autoptr(GHashTable) skip_list = NULL;
   OstreeRepoCommitModifierFlags flags = 0;
   OstreeRepoCommitModifier *modifier = NULL;
@@ -316,9 +337,10 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
 
   if (opt_statoverride_file)
     {
-      mode_adds = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+      filter_data.mode_adds = mode_adds = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+      filter_data.mode_overrides = mode_overrides = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
       if (!parse_file_by_line (opt_statoverride_file, handle_statoverride_line,
-                               mode_adds, cancellable, error))
+                               &filter_data, cancellable, error))
         goto out;
     }
 
index 012a98e0836b0bbf1e255bbf6e8f9edf3d873628..07bbeddf9d058aeebf661428339140a4558d5a99 100644 (file)
@@ -342,8 +342,11 @@ cd ${test_tmpdir}
 cat > test-statoverride.txt <<EOF
 +1048 /a/nested/2
 2048 /a/nested/3
+=384 /a/readable-only
 EOF
 cd ${test_tmpdir}/checkout-test2-4
+echo readable only > a/readable-only
+chmod 664 a/readable-only
 $OSTREE commit ${COMMIT_ARGS} -b test2-override -s "with statoverride" --statoverride=../test-statoverride.txt
 cd ${test_tmpdir}
 $OSTREE checkout test2-override checkout-test2-override
@@ -354,6 +357,7 @@ else
     test '!' -g checkout-test2-override/a/nested/2
     test '!' -u checkout-test2-override/a/nested/3
 fi
+assert_file_has_mode checkout-test2-override/a/readable-only 600
 echo "ok commit statoverride"
 
 cd ${test_tmpdir}